/*
 * FieldsPropPane.java
 *
 * Created on September 30, 2001, 4:05 PM
 *
 * Modification Log:
 * 1.00   30th Sep 2001   Tanmay   Original version.
 * 1.01   15th Jan 2002   Tanmay   Implemented access flag editor dialog
 * 1.02   30th Jan 2002   Tanmay   Moved out toggle modify button to main screen.
 * 1.03   02nd Feb 2002   Tanmay   Moved over to new attributes dialog.
 * 1.04   23rd Mar 2002   Tanmay   Corrected search behavior where all searches after
 *                                   a failed search also failed till the table 
 *                                   selection was changed manually.
 *-----------------------------------------------------------------------------------------
 *       10th Sep 2003   Tanmay   Moved to SourceForge (http://classeditor.sourceforge.net)
 *-----------------------------------------------------------------------------------------
 */

package gui;

import classfile.ClassFile;
import classfile.FieldInfo;
import classfile.AccessFlags;
import classfile.ConstantPoolInfo;
import classfile.attributes.Attributes;
import classfile.Utils;
import gui.attributes.*;
import guihelper.*;
import javax.swing.*;
import javax.swing.table.TableColumn;

/** This class displays the table model for the fields list.
 * <br><br>
 *
 * @author 	Tanmay K. Mohapatra
 * @version    1.04, 23rd Mar, 2002
 */
public class FieldsPropPane extends javax.swing.JPanel {
    private ClassFile   currClassFile;
    private int iPrevFld = -1;
    private boolean bEditable;

    public void setModifyMode(boolean bEditableIn) {
        bEditable = bEditableIn;
        FieldTableModel thisModel = (FieldTableModel)tblField.getModel();
        thisModel.setEditable(bEditable);
        btnAddFld.setEnabled(bEditable);
        btnDelFld.setEnabled(bEditable);
    }
    
    void clear() {
        iPrevFld = -1;
        tblField.setModel(new FieldTableModel(null));
        lblNumFldAttribs.setText("");
    }
    
    void refresh(){
        clear();
        if(null == currClassFile) return;
        
        TableColumn thisCol;
        FieldTableModel thisModel = new FieldTableModel(currClassFile);
        thisModel.setEditable(bEditable);
        tblField.setModel(thisModel);
        thisModel.setCellEditors(tblField);

        thisCol = tblField.getColumnModel().getColumn(0);
        thisCol.setPreferredWidth(30);
        thisCol.setMaxWidth(80);

        thisCol = tblField.getColumnModel().getColumn(1);
        thisCol.setPreferredWidth(200);
        thisCol.setMaxWidth(400);
        
        thisCol = tblField.getColumnModel().getColumn(2);
        thisCol.setPreferredWidth(200);
        thisCol.setMaxWidth(400);

        thisCol = tblField.getColumnModel().getColumn(3);
        thisCol.setPreferredWidth(200);
        thisCol.setMaxWidth(400);
        
        tblField.changeSelection(0, 1, false, false);
    }
    
    void setClassFile(ClassFile classFile) {
        currClassFile = classFile;
    }
    
    /** Creates new form FieldsPropPane */
    public FieldsPropPane() {
        initComponents();
    }
    
    private void searchField() {
        if (null == currClassFile) return;
        String sSrchStr = txtFldSearch.getText().trim();
        if (sSrchStr.length() <= 0) return;
        if(-1 == iPrevFld) return;

        FieldTableModel tblModel = (FieldTableModel)tblField.getModel();
        int iPrevFldNew = tblModel.nextIndex(iPrevFld+1, sSrchStr);
        if(iPrevFldNew >= 0) {
            iPrevFld = iPrevFldNew;
            tblField.changeSelection(iPrevFld, 1, false, false);
        }
    }
    
    private void tblFieldValueChanged(javax.swing.event.ListSelectionEvent evt) {
        if(evt.getValueIsAdjusting()) return;
        if((null == currClassFile) || (null == currClassFile.fields) || 
           (currClassFile.fields.getFieldsCount() == 0)) {
            iPrevFld = -1;
            return;
        }
        int iSelectedRow = tblField.getSelectedRow();
        if(0 > iSelectedRow) {
            iPrevFld = -1;
            return;
        }
        
        iPrevFld = iSelectedRow;
        FieldInfo thisFld = currClassFile.fields.getField(iSelectedRow);
        lblNumFldAttribs.setText(Integer.toString((null != thisFld.attributes) ? thisFld.attributes.getAttribCount() : 0));        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        java.awt.GridBagConstraints gridBagConstraints;

        jScrollPane1 = new javax.swing.JScrollPane();
        tblField = new javax.swing.JTable();
        tblField.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        ListSelectionModel tblSM = tblField.getSelectionModel();
        tblSM.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                tblFieldValueChanged(evt);
            }
        });
        srchPanel = new javax.swing.JPanel();
        jTextArea2 = new javax.swing.JTextArea();
        txtFldSearch = new javax.swing.JTextField();
        btnFldSearch = new javax.swing.JButton();
        attribPanel = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        lblNumFldAttribs = new javax.swing.JLabel();
        btnShowFldAttribs = new javax.swing.JButton();
        editPanel = new javax.swing.JPanel();
        btnAddFld = new javax.swing.JButton();
        btnDelFld = new javax.swing.JButton();

        setLayout(new java.awt.GridBagLayout());

        jScrollPane1.setAutoscrolls(true);
        tblField.setModel(new FieldTableModel(null));
        tblField.setShowHorizontalLines(false);
        jScrollPane1.setViewportView(tblField);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        add(jScrollPane1, gridBagConstraints);

        srchPanel.setLayout(new java.awt.GridBagLayout());

        srchPanel.setBorder(new javax.swing.border.TitledBorder("Search"));
        jTextArea2.setText("Enter search string below and press Find \nto search from the current position");
        jTextArea2.setBackground(new java.awt.Color(204, 204, 255));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.weighty = 1.0;
        srchPanel.add(jTextArea2, gridBagConstraints);

        txtFldSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtFldSearchActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        srchPanel.add(txtFldSearch, gridBagConstraints);

        btnFldSearch.setText("Find/Find Next");
        btnFldSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnFldSearchActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        srchPanel.add(btnFldSearch, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.weightx = 1.0;
        add(srchPanel, gridBagConstraints);

        attribPanel.setLayout(new java.awt.GridBagLayout());

        attribPanel.setBorder(new javax.swing.border.TitledBorder("Field Attributes"));
        jLabel5.setText("Number of Attributes");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        attribPanel.add(jLabel5, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
        attribPanel.add(lblNumFldAttribs, gridBagConstraints);

        btnShowFldAttribs.setText("Show/Edit");
        btnShowFldAttribs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnShowFldAttribsActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0);
        attribPanel.add(btnShowFldAttribs, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.5;
        add(attribPanel, gridBagConstraints);

        editPanel.setLayout(new java.awt.GridBagLayout());

        editPanel.setBorder(new javax.swing.border.TitledBorder("Edit"));
        btnAddFld.setText("Add New");
        btnAddFld.setEnabled(false);
        btnAddFld.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddFldActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.RELATIVE;
        editPanel.add(btnAddFld, gridBagConstraints);

        btnDelFld.setText("Delete");
        btnDelFld.setEnabled(false);
        btnDelFld.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDelFldActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        editPanel.add(btnDelFld, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 0.5;
        add(editPanel, gridBagConstraints);

    }//GEN-END:initComponents

    private void btnShowFldAttribsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowFldAttribsActionPerformed
        if (null == currClassFile) return;
        if(-1 == iPrevFld) return;
        FieldInfo fldInfo = currClassFile.fields.getField(iPrevFld);
        if (null == fldInfo) return;
        Attributes attrs = fldInfo.attributes;
        if (null == attrs) return;
        AttributesDialog attribsDial = new AttributesDialog(AttributeTreeNode.getFrameFrom(this), true);
        attribsDial.setTitle("Field Attributes");
        attribsDial.setInput(attrs, currClassFile.constantPool, bEditable);
        attribsDial.show();
    }//GEN-LAST:event_btnShowFldAttribsActionPerformed
    
    private void btnDelFldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDelFldActionPerformed
        if (-1 == iPrevFld) return;
        
        int iConfirm;

        // delete the prev fld
        FieldInfo thisFld = currClassFile.fields.getField(iPrevFld);
        String sFldStr = thisFld.accessFlags.toString() + " " +
            thisFld.getFieldDescriptor() + " " +
            thisFld.cpName.sUTFStr;
        iConfirm = JOptionPane.showConfirmDialog(null,
            "Are you sure you want to delete the field\n" + sFldStr + "?",
            "Confirm Delete", JOptionPane.YES_NO_OPTION);
        if(JOptionPane.YES_OPTION == iConfirm) {
            currClassFile.fields.deleteField(iPrevFld);
            refresh();
        }
    }//GEN-LAST:event_btnDelFldActionPerformed
        
    private void btnAddFldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddFldActionPerformed
        if (null == currClassFile) return;

        ((FieldTableModel)tblField.getModel()).addNewField();
        refresh();
        tblField.changeSelection(tblField.getModel().getRowCount()-1, 1, false, false);
    }//GEN-LAST:event_btnAddFldActionPerformed
    
    private void txtFldSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtFldSearchActionPerformed
        searchField();
    }//GEN-LAST:event_txtFldSearchActionPerformed
    
    private void btnFldSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFldSearchActionPerformed
        searchField();
    }//GEN-LAST:event_btnFldSearchActionPerformed
        
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel attribPanel;
    private javax.swing.JButton btnAddFld;
    private javax.swing.JButton btnDelFld;
    private javax.swing.JButton btnFldSearch;
    private javax.swing.JButton btnShowFldAttribs;
    private javax.swing.JPanel editPanel;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea2;
    private javax.swing.JLabel lblNumFldAttribs;
    private javax.swing.JPanel srchPanel;
    private javax.swing.JTable tblField;
    private javax.swing.JTextField txtFldSearch;
    // End of variables declaration//GEN-END:variables
}

